/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package evocarcassonne.core.generator;

import evocarcassonne.core.board.Tile;
import evocarcassonne.core.utils.Card;
import evocarcassonne.core.utils.Rand;
import evocarcassonne.core.utils.Rot;
import evocarcassonne.core.utils.ZoneType;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author nobpn
 */
public class TileGenerator {

    private static Tile tile;
    private static List<TilePattern> patterns;

    public static Tile newTile() {

        patterns = new ArrayList();

        int scenario = Rand.getInt(3);

        scenario = 0;

        switch (scenario) {

            case 0:

                // virgin
                wayVirgin();
                break;

            case 1:
                // opposite
                wayOpposite();
                break;

            case 2:
                //touchRoad
                wayTouchRoad();
                break;

        }
//        tile = new Tile(nType, eType, sType, wType);


        return tile;

    }

    private static void wayVirgin() {

        int angle = randomAngle();

        angle = 0;


        int scenario = Rand.getInt(5);

        scenario = 3;

        switch (scenario) {

            case 0:
                // Simple Double Simple
                waySDS(angle);
                genTile();
                break;

            case 1:
                // Simple Triple
                wayTriple(angle);
                genTile();
                break;

            case 2:
                //touchRoad
                wayTouchRoad();
                genTile();
                break;

            case 3:
                // Double Double
                wayDD(angle);
                genTile();
                break;

            case 4:
                // Simple Simple Simple Simple
                waySSSS(angle);
                genTile();
                break;

        }







    }

    private static void wayOpposite() {
        throw new UnsupportedOperationException("Not yet implemented");
    }

    private static void wayTouchRoad() {
        throw new UnsupportedOperationException("Not yet implemented");
    }

    // Simple Double Simple
    private static void waySDS(int angleS1) {

        int angleD = angleS1;
        int angleS2 = (angleS1 + Rot.x90) % (Rot.x180 * 2);

        if (Rand.visible()) {
//            patterns.add(TilePattern.simpleElt(angleS1));
        }
        if (Rand.visible()) {
//            patterns.add(TilePattern.simpleElt(angleS2));
        }
//        if (Rand.visible()) {
        patterns.add(TilePattern.doubleElt(angleD));
//        }
    }

    // Simple Double Simple
    private static void wayDD(int angleD) {

        int angleD2 = (angleD + Rot.x180) % (Rot.x180 * 2);

//        if (Rand.visible()) {
        patterns.add(TilePattern.doubleElt(angleD));
//        }
//        if (Rand.visible()) {
        patterns.add(TilePattern.doubleElt(angleD2));
//        }
    }

    private static void waySSSS(int angle) {

        int angleS1 = angle;
        int angleS2 = (angleS1 + Rot.x90) % (Rot.x180 * 2);
        int angleS3 = (angleS2 + Rot.x90) % (Rot.x180 * 2);
        int angleS4 = (angleS3 + Rot.x90) % (Rot.x180 * 2);

        if (Rand.visible()) {
            patterns.add(TilePattern.simpleElt(angleS1));
        }
        if (Rand.visible()) {
            patterns.add(TilePattern.simpleElt(angleS2));
        }
        if (Rand.visible()) {
            patterns.add(TilePattern.simpleElt(angleS3));
        }
        if (Rand.visible()) {
            patterns.add(TilePattern.simpleElt(angleS4));
        }
    }

    private static void wayTriple(int angleS) {

        int angleT = angleS;

        if (Rand.visible()) {
            patterns.add(TilePattern.simpleElt(angleS));
        }
        patterns.add(TilePattern.tripleElt(angleT));

    }

    private static List<Integer> createMainLink() {

        List<Integer> link = new ArrayList();

        link.add(Card.N);
        link.add(Card.E);
        link.add(Card.S);
        link.add(Card.W);

        return link;

    }

    private static int randomAngle() {
        int angle = Rand.getInt(3);

        switch (angle) {
            case 0:
                angle = Rot.x0;
                break;
            case 1:
                angle = Rot.x90;
                break;
            case 2:
                angle = Rot.x180;
                break;
            case 3:
                angle = Rot.x270;
                break;
        }
        return angle;
    }

    private static void genTile() {

        List<Integer> mainLink = createMainLink();

        ZoneType nType = ZoneType.MEADOW;
        ZoneType eType = ZoneType.MEADOW;
        ZoneType sType = ZoneType.MEADOW;
        ZoneType wType = ZoneType.MEADOW;


        for (TilePattern pattern : patterns) {

            if (pattern.linkedMainZones.contains(Card.N)) {
                nType = pattern.type;
            }
            if (pattern.linkedMainZones.contains(Card.E)) {
                eType = pattern.type;
            }
            if (pattern.linkedMainZones.contains(Card.S)) {
                sType = pattern.type;
            }
            if (pattern.linkedMainZones.contains(Card.W)) {
                wType = pattern.type;
            }

            for (Integer card : pattern.linkedMainZones) {
                mainLink.remove(card);
            }

        }

        // new Tile
        tile = new Tile(nType, eType, sType, wType);


        //links and deadends
        for (TilePattern pattern : patterns) {

            tile.addLink(pattern.linkedMainZones);


            // ROADS
            if (pattern.type == ZoneType.ROAD) {

                if (pattern.deadEnd) {
                    tile.deadEnds(pattern.deadEnds);

                    mainLink.add(pattern.deadEnds.get(0) - 1);
                    mainLink.add(pattern.deadEnds.get(0) + 1);

                } else if (pattern.touch != -1) {
                    //TODO
                } else {

//                    //smallfields for tripleroads
                    for (List<Integer> smallField : pattern.linkedFieldsZones) {
                        tile.addLink(smallField);
                    }

                    mainLink.add(pattern.linkedMainZones.get(0) - 1);
                    mainLink.add(pattern.linkedMainZones.get(pattern.linkedMainZones.size() - 1) + 1);
                }
            }

        }
        // Lien principal
        tile.addLink(mainLink);
    }
}
